@charset "UTF-8";


/*doc
---
title: "Invalid nesting in a list"
name: invalid-list-nesting
category: Warnings
---

### Description
The only child allowed in `<ul>` and `<ol>` is `<li>` - and the converse is also true.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#8.2>
* <https://www.w3.org/TR/WCAG21/#parsing>
* <https://www.w3.org/TR/WCAG21/#name-role-value>
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L313>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#the-li-element>

### Selector
```css
ul > :not(li),
ol > :not(li),
:not(ul, ol) > li
```

### Test
``` html
<ul>
  <p>I feel like I'm lost.</p>
</ul>
```
*/
ul > :not(li),
ol > :not(li),
:not(ul, ol) > li {
  @include warning('invalid-list-nesting');
}


/*doc
---
title: "Invalid sibling in a definition list"
name: invalid-def
category: Warnings
---

### Description
`<dt>` and `<dd>` should be direct adjacent siblings, and nothing else. Although multiple `<dd>` may follow a single `<dt>`.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#8.2>
* <https://www.w3.org/TR/WCAG21/#parsing>
* <https://www.w3.org/TR/WCAG21/#name-role-value>
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L312>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#the-dl-element>

### Selector
```css
dt + :not(dd),
:not(dt, dd) + dd
```

### Test
``` html
<dl>
  <dt>I need a definition, don't you think?</dt>
  <li>I'm a list item.</li>
</dl>
```
*/
dt + :not(dd),
:not(dt, dd) + dd {
  @include warning('invalid-def');
}


/*doc
---
title: "Invalid nesting in a definition list"
name: invalid-def-nesting
category: Warnings
---

### Description
`<div>`, `<dt>` and `<dd>` should be direct children of `<dl>`.
Any other imbrication may be a crime somewhere.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#8.2>
* <https://www.w3.org/TR/WCAG21/#parsing>
* <https://www.w3.org/TR/WCAG21/#name-role-value>
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L318>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#the-dl-element>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#elementdef-dl>

### Selector
```css
:not(dl) > dt,
:not(dl) > dd,
dl > :not(dt, dd, div)
```

### Test
``` html
<dl>
  <li>I'm a list item.</li>
</dl>
```
*/
:not(dl) > dt,
:not(dl) > dd,
dl > :not(dt, dd, div) {
  @include warning('invalid-def-nesting');
}


/*doc
---
title: "figcaption outside a figure"
name: invalid-figcaption-nesting
category: Warnings
---

### Description
`<figcaption>` doesn't make sense outside a `<figure>`.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#8.2>
* <https://www.w3.org/TR/WCAG21/#parsing>
* <https://www.w3.org/TR/WCAG21/#name-role-value>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#the-figcaption-element>

### Selector
```css
:not(figure) > figcaption
```

### Test
``` html
<figcaption>I'm captionning something, isn't it?</figcaption>
```
*/
:not(figure) > figcaption {
  @include warning('invalid-figcaption-nesting');
}


/*doc
---
title: "figure without the group ARIA role"
name: figure-role
category: Warnings
---

### Description
`<figure>` needs `[role="group"]` for accessibility reason.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#1.9>
* <https://www.w3.org/WAI/tutorials/images/groups/>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#the-figure-element>

### Selector
```css
figure:not([role="group"])
```

### Test
``` html
<figure>
  <img src="/static/ffoodd.png" width="144" height="144" alt="Figcaption test"/>
  <figcaption>I'm a figcaption</figcaption>
</figure>
```
*/
figure:not([role="group"]) {
  @include warning('figure-role');
}


/*doc
---
title: "Invalid nesting"
name: invalid-nesting
category: Warnings
---

### Description
Some nestings are forbidden, and do not have their own test case for now:

* `<main>`  contained in any of `<nav>`, `<aside>`, `<footer>`, `<header>` or `<article>`;
* `<address>`  containing any of `<address>`, `<nav>`, `<aside>`, `<section>`, `<footer>`, `<header>` or `<article>` — neither headings;
* `<option>` and `<optgroup>` outside a `<select>`;
* `<legend>` outside a `<fieldset>`;
* `<td>` or `<th>` outside a `<tr>`;
* direct children of a `<table>`;
* `<colgroup>` containing anything else than `<col>`.

Maybe other invalid nestings to test. Stay tuned.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#8.2>.
* <https://html.spec.whatwg.org/multipage/grouping-content.html#elementdef-main>
* <https://html.spec.whatwg.org/multipage/grouping-content.html#the-address-element>
* <https://www.w3.org/TR/WCAG21/#parsing>
* <https://www.w3.org/TR/WCAG21/#name-role-value>

### Selector
```css
nav main,
aside main,
footer main,
header main,
article main,
:not(tr) > td,
:not(tr) > th,
colgroup *:not(col),
:not(colgroup) > col,
tr > :not(td, th),
optgroup > :not(option),
:not(select) > optgroup,
:not(fieldset) > legend,
select > :not(option, optgroup),
:not(select, optgroup) > option,
table > *:not(thead, tfoot, tbody, tr, colgroup, caption),
address h1,
address h2,
address h3,
address h4,
address h5,
address h6,
address nav,
address aside,
address header,
address footer,
address address,
address article,
address section
```

### Test
``` html
<legend>I'm an legend. Am I?</legend>
```
*/
nav main,
aside main,
footer main,
header main,
article main,
:not(tr) > td,
:not(tr) > th,
colgroup *:not(col),
:not(colgroup) > col,
tr > :not(td, th),
optgroup > :not(option),
:not(select) > optgroup,
:not(fieldset) > legend,
select > :not(option, optgroup),
:not(select, optgroup) > option,
table > *:not(thead, tfoot, tbody, tr, colgroup, caption),
address h1,
address h2,
address h3,
address h4,
address h5,
address h6,
address nav,
address aside,
address header,
address footer,
address address,
address article,
address section {
  @include warning('invalid-nesting');
}


/*doc
---
title: "Misplaced div"
name: misplaced-div
category: Warnings
---

### Description
Did you know that you shouldn't add a `<div>` inside any inline element?
You could use a `<span>` instead.

### References
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L326>

### Selector
```css
b div,
i div,
q div,
em div,
abbr div,
cite div,
code div,
span div,
small div,
label div,
strong div
```

### Test
``` html
<b><div>Hey ya!</div></b>
```
*/
b div,
i div,
q div,
em div,
abbr div,
cite div,
code div,
span div,
small div,
label div,
strong div {
  @include warning('misplaced-div');
}


/*doc
---
title: "Misused sectioning tags"
name: sectioning-tags
category: Warnings
---

### Description
`<section>`, `<aside>`, `<article>` are sectioning tags.
They must not be used as wrappers!

### References
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L252>
* <https://html.spec.whatwg.org/multipage/dom.html#sectioning-content>

### Selector
```css
aside > aside:first-child,
article > aside:first-child,
aside > article:first-child,
aside > section:first-child,
section > section:first-child,
article > section:first-child,
article > article:first-child
```

### Test
``` html
<aside>
  <section>I'm wrapping, you know.</section>
</aside>
```
*/
aside > aside:first-child,
article > aside:first-child,
aside > article:first-child,
aside > section:first-child,
section > section:first-child,
article > section:first-child,
article > article:first-child {
  @include warning('sectioning-tags');
}


/*doc
---
title: "legend must be a fieldset's:first-child"
name: fieldset
category: Warnings
---

### Description
`<legend>` must be a `<fieldset>`'s`:first-child`.
Always.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#11.6>
* <https://www.w3.org/TR/WCAG21/#info-and-relationships>
* <https://www.w3.org/TR/WCAG21/#labels-or-instructions>
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L218>

### Selector
```css
fieldset > *:not(legend):first-child,
fieldset > legend:not(:first-child)
```

### Test
``` html
<fieldset>
  <label>I'm not a legend.</label>
</fieldset>
```
*/
fieldset > *:not(legend):first-child,
fieldset > legend:not(:first-child) {
  @include warning('fieldset');
}


/*doc
---
title: "summary must be a details's:first-child"
name: details
category: Warnings
---

### Description
`<summary>` must be a `<details>`'s`:first-child`.
Always.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#11.6>
* <https://www.w3.org/TR/WCAG21/#info-and-relationships>
* <https://www.w3.org/TR/WCAG21/#labels-or-instructions>
* <https://html.spec.whatwg.org/multipage/interactive-elements.html#elementdef-summary>
* <https://html.spec.whatwg.org/multipage/interactive-elements.html#elementdef-details>

### Selector
```css
details > *:not(summary):first-child,
details > summary:not(:first-child)
```

### Test
``` html
<details>
  <legend>I'm not a summary.</legend>
</details>
```
*/
details > *:not(summary):first-child,
details > summary:not(:first-child) {
  @include warning('details');
}


/*doc
---
title: "abbr should have a [title]"
name: empty-title
category: Warnings
---

### Description
Any abbreviation should give an explanation about its meaning, at least on its first occurrence.

### References
* [Opquast - Rule 5](https://checklists.opquast.com/en/web-quality-assurance/the-first-occurrence-of-an-abbreviation-or-an-acronym-in-the-body-of-any-page-provides-an-explanation-of-its-meaning)
* <https://www.w3.org/TR/WCAG21/#abbreviations>
* <https://www.w3.org/WAI/WCAG21/Techniques/general/G70>
* <https://www.w3.org/WAI/WCAG21/Techniques/general/G97>
* <https://www.w3.org/WAI/WCAG21/Techniques/general/G102>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H28>

### Selector
```css
abbr:not([title]),
abbr[title=" "],
abbr[title=""]
```

### Test
``` html
<p>Do you know about <abbr>W3C</abbr>?</p>
```
*/
abbr:not([title]),
abbr[title=" "],
abbr[title=""] {
  @include warning('empty-title');
}


/*doc
---
title: "[alt] can be empty but has to be checked"
name: empty-alt
category: Warnings
---

### Description
An alternative has to be empty when image is decorative only. In any other case, `[alt]` must be defined.
That should be double-checked.

### References
* [Opquast - Rule 111](https://checklists.opquast.com/en/web-quality-assurance/each-decorative-image-has-an-appropriate-text-alternative)
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#1.2>
* <https://www.accede-web.com/notices/html-et-css/images-et-icones/gerer-lattribut-alt-des-balises-img-et-input-typeimage/>
* <https://www.w3.org/WAI/tutorials/images/decision-tree/>
* <https://html.spec.whatwg.org/multipage/images.html#alt>
* <https://www.w3.org/TR/WCAG21/#non-text-content>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H67>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F39>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F38>

### Selector
```css
img[alt=""],
area[alt=""],
input[type="image"][alt=""],
embed[type="image"][alt=""],
object[type="image"][alt=""]
```

### Test
``` html
<img alt="" src="/static/ffoodd.png" width="144" height="144" /><span>†</span>
```
*/
img[alt=""],
area[alt=""],
input[type="image"][alt=""] {
  @include warning('empty-alt', $self-closing: true);
}

embed[type="image"][alt=""],
object[type="image"][alt=""] {
  @include warning('empty-alt');
}


/*doc
---
title: "[alt] containing file name"
name: filename-alt
category: Warnings
---

### Description
A file name in `[alt]` is probably wrongly automated… and would never ever help any user.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#1.2>
* <https://www.accede-web.com/notices/html-et-css/images-et-icones/gerer-lattribut-alt-des-balises-img-et-input-typeimage/>
* <https://www.w3.org/WAI/tutorials/images/decision-tree/>
* <https://html.spec.whatwg.org/multipage/images.html#alt>
* <https://www.w3.org/TR/WCAG21/#non-text-content>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H67>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F39>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F38>

### Selector
```css
img[alt$=".pdf"],
area[alt$=".pdf"],
input[type="image"][alt$=".pdf"],
img[alt$=".doc"],
area[alt$=".doc"],
input[type="image"][alt$=".doc"],
img[alt$=".png"],
area[alt$=".png"],
input[type="image"][alt$=".png"],
img[alt$=".jpg"],
area[alt$=".jpg"],
input[type="image"][alt$=".jpg"],
img[alt$=".gif"],
area[alt$=".gif"],
input[type="image"][alt$=".gif"],
img[alt$=".mp3"],
area[alt$=".mp3"],
input[type="image"][alt$=".mp3"],
img[alt$=".mp4"],
area[alt$=".mp4"],
input[type="image"][alt$=".mp4"],
img[alt$=".mov"],
area[alt$=".mov"],
input[type="image"][alt$=".mov"],
img[alt$=".ogg"],
area[alt$=".ogg"],
input[type="image"][alt$=".ogg"],
img[alt$=".xls"],
area[alt$=".xls"],
input[type="image"][alt$=".xls"],
img[alt$=".txt"],
area[alt$=".txt"],
input[type="image"][alt$=".txt"],
img[alt$=".zip"],
area[alt$=".zip"],
input[type="image"][alt$=".zip"],
img[alt$=".rar"],
area[alt$=".rar"],
input[type="image"][alt$=".rar"],
img[alt$=".docx"],
area[alt$=".docx"],
input[type="image"][alt$=".docx"],
img[alt$=".webp"],
area[alt$=".webp"],
input[type="image"][alt$=".webp"],
img[alt$=".apng"],
area[alt$=".apng"],
input[type="image"][alt$=".apng"],
img[alt$=".svg"],
area[alt$=".svg"],
input[type="image"][alt$=".svg"],
img[alt$=".svgz"],
area[alt$=".svgz"],
input[type="image"][alt$=".svgz"],
embed[type="image"][alt$=".pdf"],
object[type="image"][alt$=".pdf"],
embed[type="image"][alt$=".doc"],
object[type="image"][alt$=".doc"],
embed[type="image"][alt$=".png"],
object[type="image"][alt$=".png"],
embed[type="image"][alt$=".jpg"],
object[type="image"][alt$=".jpg"],
embed[type="image"][alt$=".gif"],
object[type="image"][alt$=".gif"],
embed[type="image"][alt$=".mp3"],
object[type="image"][alt$=".mp3"],
embed[type="image"][alt$=".mp4"],
object[type="image"][alt$=".mp4"],
embed[type="image"][alt$=".mov"],
object[type="image"][alt$=".mov"],
embed[type="image"][alt$=".ogg"],
object[type="image"][alt$=".ogg"],
embed[type="image"][alt$=".xls"],
object[type="image"][alt$=".xls"],
embed[type="image"][alt$=".txt"],
object[type="image"][alt$=".txt"],
embed[type="image"][alt$=".zip"],
object[type="image"][alt$=".zip"],
embed[type="image"][alt$=".rar"],
object[type="image"][alt$=".rar"],
embed[type="image"][alt$=".docx"],
object[type="image"][alt$=".docx"],
embed[type="image"][alt$=".webp"],
object[type="image"][alt$=".webp"],
embed[type="image"][alt$=".apng"],
object[type="image"][alt$=".apng"],
embed[type="image"][alt$=".svg"],
object[type="image"][alt$=".svg"],
embed[type="image"][alt$=".svgz"],
object[type="image"][alt$=".svgz"]
```

### Test
``` html
<img alt="/static/ffoodd.png" src="/static/ffoodd.png" width="144" height="144" /><span>†</span>
```
*/
$alt: ();
$self-alt: ();

@each $format in $formats {
  $alt: append($alt, unquote('img[alt$=".#{$format}"], area[alt$=".#{$format}"], input[type="image"][alt$=".#{$format}"]'), 'comma');
  $self-alt: append($self-alt, unquote('embed[type="image"][alt$=".#{$format}"], object[type="image"][alt$=".#{$format}"]'), 'comma');
}

#{$alt} {
  @include warning('filename-alt', $self-closing: true);
}

#{$self-alt} {
  @include warning('filename-alt');
}


/*doc
---
title: "Decorative image shouldn't have an accessible name"
name: decoration
category: Warnings
---

### Description
Any decorative image — with `[aria-hidden="true"]` or empty `[alt]` — shouldn't have any of those:

* `[title]`;
* `[aria-label]`;
* `[aria-labelledby]`;
* `[aria-describedby]`;
* a `<title>` child;
* or a `<desc>`.

This test currently can't check if any `<title>` nor `<desc>` child is present since `<svg>` is a replaced elements.
See [Edge cases and known issues](https://github.com/ffoodd/a11y.css/wiki/Edge-cases-and-known-issues) on a11y.css' wiki.

### References
* [Opquast - Rule 111](https://checklists.opquast.com/en/web-quality-assurance/each-decorative-image-has-an-appropriate-text-alternative)
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#1.2>
* <https://www.accede-web.com/notices/html-et-css/images-et-icones/gerer-lattribut-alt-des-balises-img-et-input-typeimage/#ancre-01>
* <https://www.w3.org/WAI/tutorials/images/decision-tree/>
* <https://www.w3.org/TR/wai-aria-1.2/#presentation>
* <https://html.spec.whatwg.org/multipage/images.html#alt>
* <https://www.w3.org/TR/WCAG21/#non-text-content>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H67>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F39>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F38>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F65>

### Selector
```css
img[alt=""][title],
img[alt=""][aria-label],
img[alt=""][aria-labelledby],
img[alt=""][aria-describedby],
area:not([href])[alt]:not([alt=""]),
area:not([href])[alt=""][title],
area:not([href])[alt=""][aria-label],
area:not([href])[alt=""][aria-labelledby],
area:not([href])[alt=""][aria-describedby],
svg[aria-hidden="true"][title],
svg[aria-hidden="true"][aria-label],
svg[aria-hidden="true"][aria-labelledby],
svg[aria-hidden="true"][aria-describedby],
canvas[aria-hidden="true"][title],
canvas[aria-hidden="true"][aria-label],
canvas[aria-hidden="true"][aria-labelledby],
canvas[aria-hidden="true"][aria-describedby],
embed[type="image"][aria-hidden="true"][title],
embed[type="image"][aria-hidden="true"][aria-label],
embed[type="image"][aria-hidden="true"][aria-labelledby],
embed[type="image"][aria-hidden="true"][aria-describedby],
object[type="image"][aria-hidden="true"][title],
object[type="image"][aria-hidden="true"][aria-label],
object[type="image"][aria-hidden="true"][aria-labelledby],
object[type="image"][aria-hidden="true"][aria-describedby],
```

### Test
``` html
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
     xmlns="http://www.w3.org/2000/svg"
     aria-hidden="true" title="Decorative SVG, you punk!">
  <rect x="400" y="100" width="400" height="200"
        fill="forestgreen" stroke="darkgreen" stroke-width="10"  />
</svg><span>†</span>
```
*/
img[alt=""][title],
img[alt=""][aria-label],
img[alt=""][aria-labelledby],
img[alt=""][aria-describedby],
area:not([href])[alt]:not([alt=""]),
area:not([href])[alt=""][title],
area:not([href])[alt=""][aria-label],
area:not([href])[alt=""][aria-labelledby],
area:not([href])[alt=""][aria-describedby],
svg[aria-hidden="true"][title],
svg[aria-hidden="true"][aria-label],
svg[aria-hidden="true"][aria-labelledby],
svg[aria-hidden="true"][aria-describedby],
embed[type="image"][aria-hidden="true"][title],
embed[type="image"][aria-hidden="true"][aria-label],
embed[type="image"][aria-hidden="true"][aria-labelledby],
embed[type="image"][aria-hidden="true"][aria-describedby], {
  @include warning('decoration', $self-closing: true);
}

canvas[aria-hidden="true"][title],
canvas[aria-hidden="true"][aria-label],
canvas[aria-hidden="true"][aria-labelledby],
canvas[aria-hidden="true"][aria-describedby],
object[type="image"][aria-hidden="true"][title],
object[type="image"][aria-hidden="true"][aria-label],
object[type="image"][aria-hidden="true"][aria-labelledby],
object[type="image"][aria-hidden="true"][aria-describedby] {
  @include warning('decoration');
}


/*doc
---
title: "[role=presentation] shouldn't be used on image"
name: presentation
category: Warnings
---

### Description
Any decorative image should be marked up with `[aria-hidden="true"]` (or empty `[alt]` if `<img>`).
`[role=presentation]` shall do the trick but at the time of writing, its support is too low compared
to empty `[alt]` or `[aria-hidden=true]`.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#1.2>
* <https://www.w3.org/WAI/tutorials/images/decorative/>


### Selector
```css
img[role="presentation"],
svg[role="presentation"],
area[role="presentation"],
embed[role="presentation"],
canvas[role="presentation"],
object[role="presentation"]
```

### Test
``` html
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
     xmlns="http://www.w3.org/2000/svg"
     role="presentation">
  <rect x="400" y="100" width="400" height="200"
        fill="forestgreen" stroke="darkgreen" stroke-width="10"  />
</svg><span>†</span>
```
*/
img[role="presentation"],
svg[role="presentation"],
area[role="presentation"],
embed[role="presentation"] {
  @include warning('presentation', $self-closing: true);
}

canvas[role="presentation"],
object[role="presentation"] {
  @include warning('presentation');
}


/*doc
---
title: "A role is needed for svg"
name: no-aria-role
category: Warnings
---

### Description
Any `<svg>` should either have `[aria-hidden="true"]` if decorative, or a `[role="img"]` if informative.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#1.2>
* <https://www.w3.org/TR/WCAG21/#non-text-content>
* <https://www.w3.org/WAI/WCAG21/Techniques/failures/F65>

### Selector
```css
svg:not([aria-hidden="true"], [role="img"])
```

### Test
``` html
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
     xmlns="http://www.w3.org/2000/svg"
     aria-label="Decorative SVG, you punk!">
  <rect x="400" y="100" width="400" height="200"
        fill="forestgreen" stroke="darkgreen" stroke-width="10"  />
</svg><span>†</span>
```
*/
svg:not([aria-hidden="true"], [role="img"]) {
  @include warning('no-aria-role', $self-closing: true);
}


/*doc
---
title: "[autoplay] should probably not be used"
name: autoplay
category: Warnings
---

### Description
A time-based media like `<audio>` or `<video>` should not `[autoplay]`, because it can be quite surprising for the user.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#4.10>
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#13.8>
* <https://www.w3.org/TR/WCAG21/#audio-control>
* <http://www.punkchip.com/autoplay-is-bad-for-all-users/>

### Selector
```css
video[autoplay],
audio[autoplay]
```

### Test
``` html
<video autoplay controls src=""></video><span>†</span>
```
*/
video[autoplay],
audio[autoplay] {
  @include warning('autoplay', $self-closing: true);
}


/*doc
---
title: "[controls] would be helpful"
name: controls
category: Warnings
---

### Description
A time-based media like `<audio>` or `<video>` would be easier to use if `[controls]` are activated for the user.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#4.11>
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#4.12>
* <https://www.w3.org/TR/WCAG21/#audio-description-or-media-alternative-prerecorded>
* <https://www.w3.org/TR/WCAG21/#keyboard>
* <https://www.w3.org/TR/WCAG21/#no-keyboard-trap>
* <https://www.w3.org/WAI/WCAG21/Techniques/general/G4>

### Selector
```css
video:not([controls]),
audio:not([controls])
```

### Test
``` html
<video src=""></video><span>†</span>
```
*/
video:not([controls]),
audio:not([controls]) {
  @include warning('controls', $self-closing: true);
}


/*doc
---
title: "Most of DOM nodes shouldn't be :empty"
name: empty-nodes
category: Warnings
---

### Description
Obviously void elements are empty, as well as `<iframe>` and `<textarea>` could be `:empty`.
Any other `:empty` tag that is not hidden is probably useless, and should be deleted.

Please note that it's disabled for tags owning a source through `[src]`. It's pretty opinionated,
but it's meant to avoid false positives on tags such as `<video>` or `<audio>` which may be
empty if they have at least one source specified through `[src]`.

###Notes

* This test only targets tags in `<body>`, since most of head's tags should be empty.
* `<button>` and `<a>` are also excluded since `button:empty` and `a:empty` are both covered by their own error.

We could use the `:blank` pseudo-class, but at this time its support is very poor. We could also use the `:-moz-only-whitespace` pseudo-class, but support is limited to Firefox and thus could invalidate our selectors stack…

### References
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L243>
* <https://html.spec.whatwg.org/multipage/syntax.html#void-elements>
* <https://drafts.csswg.org/selectors-4/#the-blank-pseudo>
* <https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-only-whitespace>
* <https://css-tricks.com/almanac/selectors/b/blank/>

### Selector
```css
body *:empty:not([hidden], [aria-hidden], [src], button, a, iframe, textarea, area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr, title)
```

### Test
``` html
<p id="empty-node_code"></p>
```
*/
/**
 * 1. An empty tag without dimensions isn't hoverable :/
 * @note Won't do anything for inline elements.
 */
body *:empty:not([hidden], [aria-hidden], [src], button, a, iframe, textarea, area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr, title) {
  @include warning('empty-nodes');
  /* 1 */
  min-height: 1px;
  min-width: 1px;
}

svg *:empty:not(title, desc, [hidden], [aria-hidden], [src], button, a, iframe, textarea, area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr) {
  @extend %a11y-reset;
}


/*doc
---
title: "A single line table may be used for layout"
name: table-layout
category: Warnings
---

### Description
A lonely `<tr>` can be a symptom of a table used for layout.
Should be double checked!

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#5.3>
* <https://www.w3.org/TR/WCAG21/#meaningful-sequence>

### Selector
```css
table:not([role="presentation"]) > tr:only-child,
table:not([role="presentation"]) > tbody > tr:only-child
```

### Test
``` html
<table>
  <caption>I'm a caption :3</caption>
  <thead>
    <tr>
      <th scope="col">Oh boy…</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>I'm a poor lonesone table-roooow!</td>
    </tr>
  </tbody>
</table>
```
*/
table:not([role="presentation"]) > tr:only-child,
table:not([role="presentation"]) > tbody > tr:only-child {
  @include warning('table-layout');
}


/*doc
---
title: "Nested tables"
name: nested-table
category: Warnings
---

### Description
There's no good reason to nest data tables: thus it probably means we're facing a layout table…

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#5.3>
* <https://www.w3.org/TR/WCAG21/#meaningful-sequence>
* <https://www.w3.org/WAI/tutorials/tables/tips/>
* <https://github.com/karlgroves/diagnostic.css/blob/39ede15ff46bd59af9f8f30efb04cbb45b6c1ba5/diagnostic.css#L175>

### Selector
```css
table table
```

### Test
``` html
<table>
  <caption>I'm a caption :3</caption>
  <thead>
    <tr>
      <th scope="col">Oh boy…</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>I'm a table-cell!</td>
    </tr>
    <tr>
      <td>
        <table>
          <caption>I'm a caption too!</caption>
          <thead>
            <tr>
              <th scope="col">Oh boy…</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>I'm a table-cell!</td>
            </tr>
            <tr>
              <td>I'm a table-cell!</td>
            </tr>
        </table>
      </td>
    </tr>
  </tbody>
</table>
```
*/
table table {
  @include warning('nested-table');
}


/*doc
---
title: "Every data table must have a caption"
name: table-caption
category: Warnings
---

### Description
`<caption>` is needed for data `<table>`.
And it must be the `:first-child`, by the way.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#5.4>
* <https://www.w3.org/TR/WCAG21/#info-and-relationships>
* <https://html.spec.whatwg.org/multipage/tables.html#the-caption-element>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H39>
* <https://github.com/imbrianj/debugCSS/blob/e04b489388870dd214aa1c1c1a07f6811210c8ef/debugCSS.css#L309>

### Selector
```css
table:not([role="presentation"]) > caption:not(:first-child),
table:not([role="presentation"]) > *:first-child:not(caption)
```

### Test
``` html
<table>
  <thead>
    <tr>
      <th id="th-one">I'm a table without a caption!</th>
      <th id="th-two">I'm a table without a caption!</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td colspan="2" headers="th-one th-two">I'm a table without a caption!</td>
    </tr>
    <tr>
      <td colspan="2" headers="th-one th-two">I'm a table without a caption!</td>
    </tr>
  </tbody>
</table>
```
*/
table:not([role="presentation"]) > caption:not(:first-child),
table:not([role="presentation"]) > *:first-child:not(caption) {
  @include warning('table-caption');
}


/*doc
---
title: "Invalid table structure"
name: table-structure
category: Warnings
---

### Description
`<thead>`, `<tfoot>` and `<tbody>` must be in this order.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#8.2>
* <https://www.w3.org/TR/WCAG21/#parsing>
* <https://www.w3.org/TR/WCAG21/#name-role-value>
* <https://github.com/imbrianj/debugCSS/blob/e04b489388870dd214aa1c1c1a07f6811210c8ef/debugCSS.css#L314>

### Selector
```css
table > tfoot ~ thead,
table > tbody ~ tfoot,
table > tbody ~ thead,
table > tfoot ~ colgroup,
table > tbody ~ colgroup,
table > tbody ~ colgroup
```

### Test
``` html
<table>
  <caption>I'm a caption</caption>
  <thead>
    <tr>
      <th scope="col">Where's my foot?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>I'm a table with tfoot done wrong.</td>
      <td>I'm a table with tfoot done wrong.</td>
    </tr>
    <tr>
      <td>I'm a table with tfoot done wrong.</td>
      <td>I'm a table with tfoot done wrong.</td>
    </tr>
  </tbody>
  <tfoot>
    <th id="th-1">I'm a table with tfoot done wrong.</th>
    <th id="th-2">I'm a table with tfoot done wrong.</th>
  </tfoot>
</table>
```
*/
table > tfoot ~ thead,
table > tbody ~ tfoot,
table > tbody ~ thead,
table > tfoot ~ colgroup,
table > tbody ~ colgroup,
table > tbody ~ colgroup {
  @include warning('table-structure');
}


/*doc
---
title: "Missing head for data table"
name: missing-thead
category: Warnings
---

### Description
`<thead>` is strongly needed if `<tbody>` is present.

### Selector
```css
table:not([role="presentation"]) > caption + tbody,
table:not([role="presentation"]) > tbody:first-child
```

### Test
``` html
<table>
  <caption>Missing thead</caption>
  <tbody>
    <tr>
      <td>I'm a table without thead.</td>
      <td>I'm a table without thead.</td>
    </tr>
    <tr>
      <td>I'm a table without thead.</td>
      <td>I'm a table without thead.</td>
    </tr>
  </tbody>
</table>
```
*/
table:not([role="presentation"]) > caption + tbody,
table:not([role="presentation"]) > tbody:first-child {
  @include warning('missing-thead');
}


/*doc
---
title: "th without [scope] or [id]"
name: th-no-scope
category: Warnings
---

### Description
`<th>` strongly needs an `[id]` or a `[scope]`.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#5.7>
* <https://www.w3.org/TR/WCAG21/#info-and-relationships>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H43>

### Selector
```css
th:not([scope], [id])
```

### Test
``` html
<table>
  <caption>Need for a [scope] or [id]</caption>
  <thead>
    <tr>
      <th>I'm a th without [scope] or [id].</th>
      <th scope="col">I'm a th with [scope].</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>I'm a td missing something.</td>
      <td>I'm a td missing something.</td>
    </tr>
    <tr>
      <td>I'm a td feeling well.</td>
      <td>I'm a td feeling well.</td>
    </tr>
  </tbody>
</table>
```
*/
th:not([scope], [id]) {
  @include warning('th-no-scope');
}


/*doc
---
title: "spacer.gif used"
name: spacer-gif
category: Warnings
---

### Description
Believe me, this still have to be tested.

### References
* <https://www.la-grange.net/2015/03/11/visible>

### Selector
```css
img[src*="1px.gif"]:not([role="presentation"]),
img[src*="1x1.gif"]:not([role="presentation"]),
img[src*="clear.gif"]:not([role="presentation"]),
img[src*="spacer.gif"]:not([role="presentation"]),
img[src*="dotclear.gif"]:not([role="presentation"]),
img[src*="transparent.gif"]:not([role="presentation"]),
img[src*="pixel-1x1-clear.gif"]:not([role="presentation"])
```

### Test
``` html
<img src="/static/spacer.gif" alt="Spacer.gif" width="100" height="100"/><span>†</span>
```
*/
img[src*="1px.gif"]:not([role="presentation"]),
img[src*="1x1.gif"]:not([role="presentation"]),
img[src*="clear.gif"]:not([role="presentation"]),
img[src*="spacer.gif"]:not([role="presentation"]),
img[src*="dotclear.gif"]:not([role="presentation"]),
img[src*="transparent.gif"]:not([role="presentation"]),
img[src*="pixel-1x1-clear.gif"]:not([role="presentation"]) {
  @include warning('spacer-gif', $self-closing: true);
}


/*doc
---
title: "Bad computed value"
name: oops
category: Warnings
---

### Description
Don't laugh, shit happens.

### Selector
```css
[id*="NaN"],
[id*="null"],
[class*="NaN"],
[class*="null"],
[id*="undefined"],
[class*="undefined"]
```

### Test
``` html
<p class="undefined">Oups, something went wrong.</p>
```
*/
[class*="NaN"],
[class*="null"],
[class*="undefined"] {
  @include warning('undefined-class');

  @include void-tags {
    @include warning('undefined-class', $self-closing: true);
  }
}

[id*="NaN"],
[id*="null"],
[id*="undefined"] {
  @include warning('undefined-id');

  @include void-tags {
    @include warning('undefined-id', $self-closing: true);
  }
}

/*doc
---
title: "JS [href]"
name: href-js
category: Warnings
---

### Description
The `[href]` attribute should not start with "javascript".
Should probably be a `<button>` or at least a `[role="button"]`, don't you think?
The only exception shall be bookmarklets.

### References
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L165>

### Selector
```css
a[href^="javascript"]:not([role="button"])
```

### Test
``` html
<a href="javascript:(function(){a11ycss=document.createElement('LINK');a11ycss.href='https://rawgit.com/ffoodd/a11y.css/master/css/a11y-en.css';a11ycss.rel='stylesheet';a11ycss.media='all';document.body.appendChild(a11ycss);})();">Please use my bookmarklet ;)</a>
```
*/
a[href^="javascript"]:not([role="button"]) {
  @include warning('href-js');
}


/*doc
---
title: "# [href]"
name: empty-href
category: Warnings
---

### Description
The `[href]` attribute is only containing `#`.
Should probably be a `<button>` or at least a `[role="button"]`, don't you think?

### References
* <https://github.com/Heydon/REVENGE.CSS/blob/master/revenge.css#L165>

### Selector
```css
a[href="#"]:not([role="button"])
```

### Test
``` html
<a href="#">Oh boy, I don't mean anything</a>
```
*/
a[href="#"]:not([role="button"]) {
  @include warning('empty-href');
}


/*doc
---
title: "[style] attribute"
name: style-attr
category: Warnings
---

### Description
Your styles should be driven by a CSS file. That's it.
And no, JS shouldn't manipulate styles: it's better to play with classes, for example.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#10.1>
* <https://www.w3.org/TR/WCAG21/#info-and-relationships>
* <https://www.w3.org/TR/WCAG21/#meaningful-sequence>

### Selector
```css
[style]
```

### Test
``` html
<div style="color: red;">I'm red. I really feel dirty.</div>
```
*/
[style] {
  @include warning('style-attr');

  @include void-tags {
    @include warning('style-attr', $self-closing: true);
  }
}


/*doc
---
title: "Unsecured [target=_blank]"
name: unsecured-target
category: Warnings
---

### Description
`[target="_blank"]` links might be used for phishing.
This is not actually an accessibility related issue, but everything helping users is welcome.

### References*
* <https://mathiasbynens.github.io/rel-noopener/>
* <https://html.spec.whatwg.org/multipage/semantics.html#link-type-noopener>
* <https://html.spec.whatwg.org/multipage/semantics.html#link-type-noreferrer>
* <https://dev.to/ben/the-targetblank-vulnerability-by-example>

### Selector
```css
[target$="blank"]:not([rel]),
[target$="blank"]:not([rel*="noopener"]),
[target$="blank"]:not([rel*="noreferrer"])
```

### Test
``` html
<a href="/" target="_blank">I feel vulnerable…</a>
```
*/
[target$="blank"]:not([rel]),
[target$="blank"]:not([rel*="noopener"]),
[target$="blank"]:not([rel*="noreferrer"]) {
  @include warning('unsecured-target');
}


/*doc
---
title: "Missing [aria-level]"
name: no-aria-level
category: Warnings
---

### Description
Though `[aria-level]` is not required by ARIA specification, it's actually better to specify it.

### References
* <https://www.w3.org/TR/wai-aria-1.2/#aria-level>
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#9.1>
* <https://github.com/DISIC/rgaa_methodologie/blob/master/Check-css/check-heading.css>
* <https://www.w3.org/TR/wai-aria-1.2/#heading>
* <https://www.w3.org/WAI/WCAG21/Techniques/aria/ARIA12>
* <https://www.w3.org/WAI/WCAG21/Techniques/general/G141>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H42>

### Selector
```css
[role="heading"]:not([aria-level])
```

### Test
``` html
<strong role="heading">Heading with undefined level</strong>
```
*/
[role="heading"]:not([aria-level]) {
  @include warning('no-aria-level');
}


/*doc
---
title: "A label without a [for] attribute"
name: no-for
category: Warnings
---

### Description
A `<label>` is labelling something, in theory.
Although implicitly labelling form controls is accepted, it's probably better to double-check that form control is *really* nested in its `<label>`.

### References
* <https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#11.1.2>
* <https://github.com/DISIC/rgaa_referentiel_en/blob/44e2bee0c710e37ca49901b1e6b8fae9b553fd5d/criteria.html#L3981>
* <https://www.w3.org/WAI/WCAG21/Techniques/html/H44>
* <https://www.w3.org/WAI/tutorials/forms/labels/>
* <https://make.wordpress.org/accessibility/2017/01/16/testing-form-functionality-with-different-assistive-technology/>
* <https://www.w3.org/TR/WCAG21/#labels-or-instructions>
* <https://www.w3.org/TR/WCAG21/#headings-and-labels>
* <https://www.w3.org/TR/WCAG21/#info-and-relationships>

### Selector
```css
label:not([for])
```

### Test
``` html
<label>Guess what?</label>
```
*/
label:not([for]) {
  @include warning('no-for');
}


/*doc
---
title: "Mismatching [dir] and [lang] attributes"
name: mismatched-dir
category: Warnings
---

### Description
Some languages — like Arabic or Hebrew — requires a text direction switch usin `[dir="rtl"]`, as default text direction is left-to-right.
This also requires to check any in-page language change (marked up with `[lang]`) in Arabic or Hebrew content to define `[dir]` too.

### References
* <https://alphagov.github.io/accessibility-tool-audit/test-cases.html#languageofcontent>
* <https://www.w3.org/International/questions/qa-html-dir>
* <https://www.w3.org/International/articles/inline-bidi-markup/#dirattribute>
* <https://html.spec.whatwg.org/multipage/dom.html#the-dir-attribute>

### Selector
```css
[lang="ar"]:not([dir="rtl"]),
[lang="he"]:not([dir="rtl"]),
[lang="ar"] [lang]:not([dir="ltr"]),
[lang="he"] [lang]:not([dir="ltr"]),
[dir="rtl"]:not([lang="ar"], [lang="he"])
```

### Test
``` html
<p dir="rtl" lang="en">Well, I'm kinda disoriented…</p>
```
*/
[lang="ar"]:not([dir="rtl"]),
[lang="he"]:not([dir="rtl"]),
[lang="ar"] [lang]:not([dir="ltr"]),
[lang="he"] [lang]:not([dir="ltr"]),
[dir="rtl"]:not([lang="ar"], [lang="he"]) {
  @include warning('mismatched-dir');
}
